package com.alibaba.citrus.cr.sales.plan.facade.service.statistics;

import com.alibaba.citrus.cr.common.annotation.EpochTransactional;
import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.common.exception.RepositoryException;
import com.alibaba.citrus.cr.common.lock.RedisLock;
import com.alibaba.citrus.cr.common.util.CalculatePercentage;
import com.alibaba.citrus.cr.sales.plan.annotation.CommonRedisLock;
import com.alibaba.citrus.cr.sales.plan.api.salesplan.SalesPlanLineWriteService;
import com.alibaba.citrus.cr.sales.plan.api.salesplan.SalesPlanQueryService;
import com.alibaba.citrus.cr.sales.plan.contants.SalesPlanLockKey;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.EditSalesPlanAdjustDetailRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.UpdateAdjustCountRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.response.DepartmentResponse;
import com.alibaba.citrus.cr.sales.plan.dto.api.response.GoodsOwnershipDepartmentResponse;
import com.alibaba.citrus.cr.sales.plan.facade.service.salesplan.publish.SharePie;
import com.alibaba.citrus.cr.sales.plan.facade.service.setting.SalesPlanScItemWriteServiceImpl;
import com.alibaba.citrus.cr.sales.plan.functions.ability.model.DeletePlanScItemAbilityRequest;
import com.alibaba.citrus.cr.sales.plan.functions.salesplan.SalesPlanLineEntity;
import com.alibaba.citrus.cr.sales.plan.functions.salesplan.SalesPlanScItemStatEntity;
import com.alibaba.citrus.cr.sales.plan.functions.salesplan.SalesPlanStatAbility;
import com.alibaba.citrus.cr.sales.plan.functions.salesplan.adjust.SalesPlanAdjustDetailAbility;
import com.alibaba.citrus.cr.sales.plan.functions.salesplan.adjust.SalesPlanAdjustDetailEntity;
import com.alibaba.citrus.cr.sales.plan.model.SalesPlanLineStatusEnum;
import com.alibaba.citrus.cr.sales.plan.model.enums.SalesStatBizTypeEnum;
import com.alibaba.citrus.cr.sales.plan.model.features.SalesPlanAdjustDetailFeatures;
import com.alibaba.citrus.cr.sales.plan.repository.SalesPlanScItemStatRepository;
import com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanAdjustDetailSDO;
import com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanLineSDO;
import com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanSDO;
import com.alibaba.citrus.cr.sales.plan.sdo.SalesPlanStatScItemSDO;
import com.alibaba.citrus.cr.sales.plan.api.statistics.SalesPlanScItemStatWriteService;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.DeleteSalesPlanScItemStatRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.QueryPlanScItemStatRequest;
import com.alibaba.citrus.cr.sales.plan.dto.api.request.QuerySalesPlanRequest;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.cz.base.tool.result.Results;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.contants.BcOrderConstants;
import com.epoch.app.bcorder.model.dto.PlanScItemLoadListRequest;
import com.epoch.app.bcorder.model.dto.PlanStatServiceRequest;
import com.epoch.app.bcorder.model.dto.PlanStatServiceResponse;
import com.epoch.app.bcorder.sales_plan.planscitem.dto.LoadPlanScItemListRequest;
import com.epoch.app.bcorder.sales_plan.planscitem.model.PlanScItem;
import com.epoch.app.bcorder.sales_plan.planscitem.service.PlanScItemService;
import com.epoch.app.bcorder.sales_plan.salesplanadjustdetail.dto.LoadSalesPlanAdjustDetailListRequest;
import com.epoch.app.bcorder.sales_plan.salesplanadjustdetail.model.SalesPlanAdjustDetail;
import com.epoch.app.bcorder.sales_plan.salesplanadjustdetail.service.SalesPlanAdjustDetailService;
import com.epoch.app.bcorder.sales_plan.salesplandetail.dto.LoadSalesPlanDetailListRequest;
import com.epoch.app.bcorder.sales_plan.salesplandetail.model.SalesPlanDetail;
import com.epoch.app.bcorder.sales_plan.salesplandetail.service.SalesPlanDetailService;
import com.epoch.app.bcorder.service.SalesPlanService;
import com.epoch.app.crpricecenter.model.dto.ItemResponse;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author yuhailin
 * @description:
 * @date 2021-09-27 10:38
 */
@Component
public class SalesPlanScItemStatWriteServiceImpl implements SalesPlanScItemStatWriteService {
    private final Log log = Log.getLogger(SalesPlanScItemStatWriteServiceImpl.class);

    @Resource
    private SalesPlanScItemStatRepository salesPlanScItemStatRepository;

    @Resource
    private SalesPlanStatAbility salesPlanStatAbility;

    @Resource
    private SalesPlanDetailService salesPlanDetailService;

    @Resource
    private SalesPlanService salesPlanService;

    @Resource
    private PlanScItemService planScItemService;

    @Resource
    private SalesPlanQueryService salesPlanQueryService;

    @Resource
    private SalesPlanAdjustDetailService salesPlanAdjustDetailService;

    @Resource
    private SalesPlanLineWriteService salesPlanLineWriteService;



    @FacadeInvoker
    @Override
    public Result<Boolean> editSalesPlanScItem(SalesPlanStatScItemSDO salesPlanScItemStatSDO) {
        QueryPlanScItemStatRequest queryPlanScItemStatRequest = new QueryPlanScItemStatRequest();
        queryPlanScItemStatRequest.setId(salesPlanScItemStatSDO.getId().toString());
        SalesPlanStatScItemSDO salesPlanScItem = salesPlanScItemStatRepository.getSalesPlanScItem(queryPlanScItemStatRequest);
        salesPlanScItem.setId(salesPlanScItemStatSDO.getId());
        salesPlanScItem.setTaskCount(salesPlanScItemStatSDO.getTaskCount());
        if (salesPlanScItemStatSDO.getTaskMoney() != null && salesPlanScItemStatSDO.getTaskMoney() != 0) {
            salesPlanScItem.setTaskMoney(salesPlanScItemStatSDO.getTaskMoney());
        }
/*        if (salesPlanScItemStatSDO.getReturnCount() != null && salesPlanScItemStatSDO.getReturnCount() != 0) {
            salesPlanScItem.setReturnCount(salesPlanScItemStatSDO.getReturnCount());
        }*/
        salesPlanScItem.setMonthMiddleTaskCount(salesPlanScItemStatSDO.getMonthMiddleTaskCount());
        salesPlanScItem.setMonthFirstTaskCount(salesPlanScItemStatSDO.getMonthFirstTaskCount());
        salesPlanScItem.setMonthLastTaskCount(salesPlanScItemStatSDO.getMonthLastTaskCount());
        if (salesPlanScItemStatSDO.getMonthFirstCount() != null && salesPlanScItemStatSDO.getMonthFirstCount() != 0) {
            salesPlanScItem.setMonthFirstReturnCount(salesPlanScItemStatSDO.getMonthFirstCount());
            salesPlanScItem.setMonthMiddleReturnCount(salesPlanScItemStatSDO.getMonthMiddleCount());
            salesPlanScItem.setMonthLastReturnCount(salesPlanScItemStatSDO.getMonthLastCount());
        }
        // 构造实体
        SalesPlanScItemStatEntity salesPlanScItemStatEntity = SalesPlanScItemStatEntity.of(salesPlanScItem);
        return Result.success(salesPlanScItemStatEntity.editSalesPlanScItem());
    }

    @FacadeInvoker
    @Override
    public Result<Boolean> updateSalesPlanScItemStatus(SalesPlanStatScItemSDO salesPlanScItemStatSDO) {
        SalesPlanScItemStatEntity salesPlanScItemStatEntity = SalesPlanScItemStatEntity.of(salesPlanScItemStatSDO);
        return Result.success(salesPlanScItemStatEntity.updateSalesPlanScItemStatus());
    }

    @FacadeInvoker
    @Override
    public Result<Boolean> deletePlanScItem(DeleteSalesPlanScItemStatRequest deleteSalesPlanScItemStatRequest) {
        DeletePlanScItemAbilityRequest deletePlanScItemAbilityRequest = new DeletePlanScItemAbilityRequest();
        deletePlanScItemAbilityRequest.setId(deleteSalesPlanScItemStatRequest.getId().toString());
        return Result.success(salesPlanStatAbility.deletePlanScItem(deletePlanScItemAbilityRequest));
    }

    /**
     * 部门提报量分解
     * @param departmentResponse
     * @return
     */
    @FacadeInvoker
    @Override
    public Result<Boolean> departmentDecomposition(GoodsOwnershipDepartmentResponse departmentResponse) {
        if (StringUtils.isBlank(departmentResponse.getPlanId())) {
            throw new FacadeException("OTS-02-001-00-15-006");
        }
        if (StringUtils.isBlank(departmentResponse.getScItemId())) {
            throw new FacadeException("OTS-01-005-02-15-012");
        }
        if (Objects.isNull(departmentResponse.getPoolType())) {
            throw new FacadeException("OTS-02-004-01-15-002");
        }
        if (Objects.isNull(departmentResponse.getMapList())) {
            return Result.success(true);
        }
        //查询出当前货品数据 部门维度有哪些
        Result<List<PlanScItem>> listResult = planScItemService.loadPlanScItemList(LoadPlanScItemListRequest.builder()
                .planId(departmentResponse.getPlanId())
                .scItemId(departmentResponse.getScItemId())
                .poolType(departmentResponse.getPoolType())
                .bizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType())
                .build());
        if (CollectionUtils.isEmpty(listResult.getResult())) {
            throw new FacadeException("OTS-02-005-00-15-038");
        }
        //获取当前货品归属于哪些部门  并每个部门分别提报量为多少（monthCount）
        //Map<String, Integer> departmentKeyValuePair = listResult.getResult().stream().filter(t -> t.getBizId() != null).collect(Collectors.toMap(PlanScItem::getBizId, PlanScItem::getMonthCount, (k1, k2) -> k1));
        //如果进行修改了某些部门的提报量(month_count)
        //首先获取其是修改哪些部门   获取其中所有的Key
        List<Map<String, Integer>> mapList = departmentResponse.getMapList();

        //根据bizId部门编码 +月度计划ID+货品ID 查找明细列表进行修改MonthCount(提报量)
        LoadSalesPlanDetailListRequest listRequest = new LoadSalesPlanDetailListRequest();
        listRequest.setPlanId(Long.valueOf(departmentResponse.getPlanId()));
        listRequest.setLimit(1000);
        listRequest.setScItemId(departmentResponse.getScItemId());
        //listRequest.setOrgSalesDepartmentCode(orgSalesDepartmentCode);
        Result<List<SalesPlanDetail>> salesPlanDetailList = salesPlanDetailService.loadSalesPlanDetailList(listRequest);
        if (Objects.isNull(salesPlanDetailList)||CollectionUtils.isEmpty(salesPlanDetailList.getResult()) || salesPlanDetailList.getTotal() == 0) {
            throw new FacadeException("OTS-02-004-01-15-043");
        }
        QuerySalesPlanRequest querySalesPlanRequest = new QuerySalesPlanRequest();
        querySalesPlanRequest.setId(departmentResponse.getPlanId());
        Result<SalesPlanSDO> salesPlan = salesPlanQueryService.getSalesPlan(querySalesPlanRequest);
        SalesPlanSDO salesPlanSDO = salesPlan.getResult();
        for (Map<String, Integer> stringIntegerMap : mapList) {
            Set<String> bizIds = stringIntegerMap.keySet();
            for (String orgSalesDepartmentCode : bizIds) {
                //过滤出 明细数据中 跟当前bizId 部门编码一样 并且是当前货品的数据
                List<SalesPlanDetail> decomposeDataList = salesPlanDetailList.getResult().stream().filter(t -> t.getOrgSalesDepartmentCode().equals(orgSalesDepartmentCode) && t.getScItemId().equals(departmentResponse.getScItemId())).collect(Collectors.toList());

                //修改前的提报量
                int beforeModificationCount = decomposeDataList.stream().mapToInt(SalesPlanDetail::getMonthCount).sum();

                //原提报量为0 不参与分解
                if (0==beforeModificationCount){
                    continue;
                }
                //获取当前BizId所对应的value值(修改后的提报量)
                Integer afterModificationCount = stringIntegerMap.get(orgSalesDepartmentCode);

                // 修改前明细提报所占比例
                decomposeDataList.stream().filter(salesPlanDetail -> salesPlanDetail.getMonthCount() != 0).forEach(it -> {
                    BigDecimal rate = new BigDecimal(it.getMonthCount()).divide(new BigDecimal(beforeModificationCount), 2, RoundingMode.DOWN);
                    it.setMonthCount(new BigDecimal(afterModificationCount).multiply(rate).intValue());
                });

                //第一次分配后的剩余数
                int afterFirst = afterModificationCount-decomposeDataList.stream().mapToInt(SalesPlanDetail::getMonthCount).sum();
                if (afterFirst>0){
                    List<SalesPlanDetail> sortedList = decomposeDataList.stream().filter(salesPlanDetail -> salesPlanDetail.getMonthCount() != 0).sorted(Comparator.comparing(SalesPlanDetail::getMonthCount)).collect(Collectors.toList());
                    int size = sortedList.size();
                    if (size>0){
                        for (int i = 0; i < afterFirst; i++) {
                            int index = i % size;
                            sortedList.get(index).setMonthCount(sortedList.get(index).getMonthCount()+1);
                        }
                    }else {
                        int size1 = decomposeDataList.size();
                        for (int i = 0; i < afterFirst; i++) {
                            int index = i % size1;
                            decomposeDataList.get(index).setMonthCount(decomposeDataList.get(index).getMonthCount()+1);
                        }
                    }
                }

              /*  //根据这个部门(所修改的提报量加上之前的量)/原先的量 得到修改的比例 最后进行进行分解到这个货品归属的的部门下
                Integer proportion = (beforeModificationCount + afterModificationCount) / beforeModificationCount;
                //拿最后的结果量去分解给当前所有部门
                Map<String, BigDecimal> map = Maps.newHashMap();
                decomposeDataList.stream().filter(salesPlanDetail -> salesPlanDetail.getMonthCount() != 0).forEach(it -> {
                    //如果当前数据本身就没有提报量 那么就不参与分解
                    //根据数据唯一ID 所对应的那条数据占比最后进行分
                    map.put(it.getId().toString(), new BigDecimal(proportion).multiply(new BigDecimal(it.getMonthCount())));
                });
                SharePie sharePie = new SharePie(map);
                Map<String, BigDecimal> bigDecimalMap = sharePie.share(new BigDecimal(afterModificationCount), 0, RoundingMode.HALF_UP);*/

                //获取分解后每条明细有多少提报量 准备进行上中下 三旬分解   然后进行落库
                for (SalesPlanDetail it : decomposeDataList) {
                    updateSalesPlanLine(it, salesPlanSDO);
                }
            }
        }
        //更新成功后  进行汇总更新
        PlanStatServiceResponse planStatServiceResponse = salesPlanService.planStatService(PlanStatServiceRequest.builder().planId(departmentResponse.getPlanId()).build());
        if (!planStatServiceResponse.getSuccess()) {
            throw new FacadeException("OTS-02-006-00-16-010");
        }
        return Result.success(true);
    }

    /**
     * 渠道提报量分解
     * @param channelResponse
     * @return
     */
    @FacadeInvoker
    @Override
    public Result<Boolean> channelDecomposition(GoodsOwnershipDepartmentResponse channelResponse) {
        if (StringUtils.isBlank(channelResponse.getPlanId())) {
            throw new FacadeException("OTS-02-001-00-15-006");
        }
        if (StringUtils.isBlank(channelResponse.getScItemId())) {
            throw new FacadeException("OTS-01-005-02-15-012");
        }
        if (Objects.isNull(channelResponse.getPoolType())) {
            throw new FacadeException("OTS-02-004-01-15-002");
        }
        if (Objects.isNull(channelResponse.getMapList())) {
            return Result.success(true);
        }

        Result<List<PlanScItem>> listResult = planScItemService.loadPlanScItemList(LoadPlanScItemListRequest.builder()
                .planId(channelResponse.getPlanId())
                .scItemId(channelResponse.getScItemId())
                .poolType(channelResponse.getPoolType())
                .bizType(SalesStatBizTypeEnum.SALES_CHANNEL.getBizType())
                .build());
        if (CollectionUtils.isEmpty(listResult.getResult())) {
            throw new FacadeException("OTS-02-005-00-15-038");
        }

        List<Map<String, Integer>> mapList = channelResponse.getMapList();

        LoadSalesPlanDetailListRequest listRequest = new LoadSalesPlanDetailListRequest();
        listRequest.setPlanId(Long.valueOf(channelResponse.getPlanId()));
        listRequest.setLimit(1000);
        listRequest.setScItemId(channelResponse.getScItemId());
        Result<List<SalesPlanDetail>> salesPlanDetailList = salesPlanDetailService.loadSalesPlanDetailList(listRequest);
        if (Objects.isNull(salesPlanDetailList)||CollectionUtils.isEmpty(salesPlanDetailList.getResult()) || salesPlanDetailList.getTotal() == 0) {
            throw new FacadeException("OTS-02-004-01-15-043");
        }
        QuerySalesPlanRequest querySalesPlanRequest = new QuerySalesPlanRequest();
        querySalesPlanRequest.setId(channelResponse.getPlanId());
        Result<SalesPlanSDO> salesPlan = salesPlanQueryService.getSalesPlan(querySalesPlanRequest);
        SalesPlanSDO salesPlanSDO = salesPlan.getResult();
        for (Map<String, Integer> stringIntegerMap : mapList) {
            Set<String> bizIds = stringIntegerMap.keySet();
            for (String orgSalesChannelCode : bizIds) {
                //过滤出 明细数据中 跟当前bizId 部门编码一样 并且是当前货品的数据
                List<SalesPlanDetail> decomposeDataList = salesPlanDetailList.getResult().stream().filter(t -> t.getOrgSalesChannelCode().equals(orgSalesChannelCode) && t.getScItemId().equals(channelResponse.getScItemId())).collect(Collectors.toList());

                //修改前的提报量
                int beforeModificationCount = decomposeDataList.stream().mapToInt(SalesPlanDetail::getMonthCount).sum();

                //原提报量为0 不参与分解
                if (0==beforeModificationCount){
                    continue;
                }
                //获取当前BizId所对应的value值(修改后的提报量)
                Integer afterModificationCount = stringIntegerMap.get(orgSalesChannelCode);

                // 修改前明细提报所占比例
                decomposeDataList.stream().filter(salesPlanDetail -> salesPlanDetail.getMonthCount() != 0).forEach(it -> {
                    BigDecimal rate = new BigDecimal(it.getMonthCount()).divide(new BigDecimal(beforeModificationCount), 2, RoundingMode.DOWN);
                    it.setMonthCount(new BigDecimal(afterModificationCount).multiply(rate).intValue());
                });

                //第一次分配后的剩余数
                int afterFirst = afterModificationCount-decomposeDataList.stream().mapToInt(SalesPlanDetail::getMonthCount).sum();
                if (afterFirst>0){
                    List<SalesPlanDetail> sortedList = decomposeDataList.stream().filter(salesPlanDetail -> salesPlanDetail.getMonthCount() != 0).sorted(Comparator.comparing(SalesPlanDetail::getMonthCount)).collect(Collectors.toList());
                    int size = sortedList.size();
                    if (size>0){
                        for (int i = 0; i < afterFirst; i++) {
                            int index = i % size;
                            sortedList.get(index).setMonthCount(sortedList.get(index).getMonthCount()+1);
                        }
                    }else {
                        int size1 = decomposeDataList.size();
                        for (int i = 0; i < afterFirst; i++) {
                            int index = i % size1;
                            decomposeDataList.get(index).setMonthCount(decomposeDataList.get(index).getMonthCount()+1);
                        }
                    }
                }

              /*  //根据这个部门(所修改的提报量加上之前的量)/原先的量 得到修改的比例 最后进行进行分解到这个货品归属的的部门下
                Integer proportion = (beforeModificationCount + afterModificationCount) / beforeModificationCount;
                //拿最后的结果量去分解给当前所有部门
                Map<String, BigDecimal> map = Maps.newHashMap();
                decomposeDataList.stream().filter(salesPlanDetail -> salesPlanDetail.getMonthCount() != 0).forEach(it -> {
                    //如果当前数据本身就没有提报量 那么就不参与分解
                    //根据数据唯一ID 所对应的那条数据占比最后进行分
                    map.put(it.getId().toString(), new BigDecimal(proportion).multiply(new BigDecimal(it.getMonthCount())));
                });
                SharePie sharePie = new SharePie(map);
                Map<String, BigDecimal> bigDecimalMap = sharePie.share(new BigDecimal(afterModificationCount), 0, RoundingMode.HALF_UP);*/

                //获取分解后每条明细有多少提报量 准备进行上中下 三旬分解   然后进行落库
                for (SalesPlanDetail it : decomposeDataList) {
                    updateSalesPlanLine(it, salesPlanSDO);
                }
            }
        }
        //更新成功后  进行汇总更新
        PlanStatServiceResponse planStatServiceResponse = salesPlanService.planStatService(PlanStatServiceRequest.builder().planId(channelResponse.getPlanId()).build());
        if (!planStatServiceResponse.getSuccess()) {
            throw new FacadeException("OTS-02-006-00-16-010");
        }
        return Result.success(true);
    }

    private void updateSalesPlanLine(SalesPlanDetail it, SalesPlanSDO salesPlanSDO){
        Integer departmentMonthCount = it.getMonthCount();
        //先将原本数据进行拷贝到准备进行修改
        SalesPlanLineSDO salesPlanLineSDO = new SalesPlanLineSDO();
        BeanUtils.copyProperties(it, salesPlanLineSDO);
        salesPlanLineSDO.setPlanId(String.valueOf(it.getPlanId()));
        //分解的每个部门按照最后分比列
        salesPlanLineSDO.setMonthCount(departmentMonthCount);
        //上旬量  比例 3
        BigDecimal monthFirstProprtion = new BigDecimal(30);
        BigDecimal firstCount = monthFirstProprtion.multiply(new BigDecimal(Optional.ofNullable(departmentMonthCount).orElse(0)));
        Integer monthFirstCount = firstCount.divide(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_DOWN).intValue();
        salesPlanLineSDO.setMonthFirstCount(monthFirstCount);
        //下旬量  比列 3
        BigDecimal monthLastProprtion = new BigDecimal(30);
        BigDecimal LastCount = monthLastProprtion.multiply(new BigDecimal(Optional.ofNullable(departmentMonthCount).orElse(0)));
        Integer monthLastCount = LastCount.divide(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_DOWN).intValue();
        salesPlanLineSDO.setMonthLastCount(monthLastCount);
        //中旬量  剩下的全是中旬的
        Integer monthMiddleCount = Optional.ofNullable(departmentMonthCount).orElse(0) - (monthFirstCount + monthLastCount);
        salesPlanLineSDO.setMonthMiddleCount(monthMiddleCount);

        //计算折前计划金额
        long costInsuranceFreight = Objects.nonNull(it.getCostInsuranceFreight()) ? it.getCostInsuranceFreight() : 0;
        long beforeMonthMoney = Optional.ofNullable(departmentMonthCount).orElse(0) * costInsuranceFreight;
        salesPlanLineSDO.setBeforeMonthMoney(beforeMonthMoney);
        //计算折后计划金额  折后计划金额=折前计划金额*(1-预估价格折扣率)
        salesPlanLineSDO.calculateMonthMoney(salesPlanSDO.getEstimateDiscount());
        //合同差量  合同差量=month_count（计划数量）-month_contract_count（合同量）
        Integer contractDifferenceCount = Optional.ofNullable(departmentMonthCount).orElse(0) - it.getMonthContractCount();
        salesPlanLineSDO.setContractDifferenceCount(contractDifferenceCount);
        //合同差金额 合同差金额=计划折前合同金额 -计划折前金额
        long contractDifferenceMoney = it.getBeforeMonthContractMoney() - beforeMonthMoney;
        salesPlanLineSDO.setContractDifferenceMoney(contractDifferenceMoney);
        //计算折前满足度 折前满足度=折前计划金额/折前合同金额
        BigDecimal beforeContractSatisfaction = CalculatePercentage.retainTwo(beforeMonthMoney, it.getBeforeMonthContractMoney());
        salesPlanLineSDO.setBeforeContractSatisfaction(beforeContractSatisfaction);
        //计算折后满足度  折后满足度 = 折后计划金额/折后合同金额
        BigDecimal contractSatisfaction = CalculatePercentage.retainTwo(it.getMonthMoney(), it.getMonthContractMoney());
        salesPlanLineSDO.setContractSatisfaction(contractSatisfaction);
        //修改滚动量
        salesPlanLineSDO.setM1RollingPlanCount(Optional.ofNullable(it.getM1RollingPlanCount()).orElse(0));
        salesPlanLineSDO.setM2RollingPlanCount(Optional.ofNullable(it.getM2RollingPlanCount()).orElse(0));
        salesPlanLineSDO.setM3RollingPlanCount(Optional.ofNullable(it.getM3RollingPlanCount()).orElse(0));
        salesPlanLineSDO.setGmtModified(new Date());
        //到岸折前金额
        long outboundPrice = Objects.nonNull(it.getOutboundPrice()) ? it.getOutboundPrice() : 0;
        long beforeMonthOutboundMoney = Optional.ofNullable(departmentMonthCount).orElse(0) * outboundPrice;
        salesPlanLineSDO.setBeforeMonthOutboundMoney(beforeMonthOutboundMoney);
        //到岸折后金额 到岸折后金额=到岸折前金额*(1-预估价格折扣率)
        salesPlanLineSDO.calculateMonthOutboundMoney(salesPlanSDO.getEstimateDiscount());
        //总量不为0时，状态为已完成
        if (0 != Optional.ofNullable(salesPlanLineSDO.getMonthCount()).orElse(0)){
            salesPlanLineSDO.setStatus(SalesPlanLineStatusEnum.FINISH.getStatus());
        } else {
            salesPlanLineSDO.setStatus(SalesPlanLineStatusEnum.DRAFT.getStatus());
        }
        //总量与三旬分配完后进行落库
        SalesPlanLineEntity salesPlanLineEntity = SalesPlanLineEntity.of(salesPlanLineSDO);
        Integer count = salesPlanLineEntity.doEdit();
        if (count < 1) {
            throw new FacadeException("OTS-02-006-00-16-009");
        }
    }

    /**
     * 部门调整量分解
     * @param departmentResponse
     * @return
     */
    @FacadeInvoker
    @Override
    public Result<Boolean> departmentAdjustDecomposition(GoodsOwnershipDepartmentResponse departmentResponse) {
        checkRequestParam(departmentResponse);
        if (Objects.isNull(departmentResponse.getMapList2())) {
            return Result.success(true);
        }
        String lockKey = SalesPlanLockKey.getAdjustCountDecompositionLockKey(departmentResponse.getAdjustId(),departmentResponse.getScItemId());
        try (RedisLock lock = new RedisLock(BcOrderConstants.REDIS_CACHE_CODE(), lockKey)) {
            boolean locked = lock.lock();
            if (!locked) {
                return Result.fail("OTS-02-007-00-16-001", "不能同时分解相同货品调整量，请稍候操作！");
            }

            //查询部门货品维度汇总数据
            Result<List<PlanScItem>> departmentStatResult = planScItemService.loadPlanScItemList(LoadPlanScItemListRequest.builder()
                    .planId(departmentResponse.getPlanId())
                    .scItemId(departmentResponse.getScItemId())
                    .poolType(departmentResponse.getPoolType())
                    .bizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType())
                    .build());
            if (CollectionUtils.isEmpty(departmentStatResult.getResult())) {
                throw new FacadeException(ErrorMessage.code("OTS-02-005-00-15-038"));
            }
            //部门：任务量
            List<PlanScItem> filterList = departmentStatResult.getResult().stream().filter(t -> t.getBizId() != null).collect(Collectors.toList());
            Map<String, Integer> departmentTaskCountMap = filterList.stream().collect(Collectors.toMap(PlanScItem::getBizId, PlanScItem::getTaskCount, (k1, k2) -> k1));
            Map<String, Integer> departmentFirstTaskCountMap = filterList.stream().collect(Collectors.toMap(PlanScItem::getBizId, PlanScItem::getMonthFirstTaskCount, (k1, k2) -> k1));
            Map<String, Integer> departmentMiddleTaskCountMap = filterList.stream().collect(Collectors.toMap(PlanScItem::getBizId, PlanScItem::getMonthMiddleTaskCount, (k1, k2) -> k1));
            Map<String, Integer> departmentLastTaskCountMap = filterList.stream().collect(Collectors.toMap(PlanScItem::getBizId, PlanScItem::getMonthLastTaskCount, (k1, k2) -> k1));

            //计划明细货品：任务量
            LoadSalesPlanDetailListRequest loadSalesPlanDetailListRequest = new LoadSalesPlanDetailListRequest();
            loadSalesPlanDetailListRequest.setPlanId(Long.valueOf(departmentResponse.getPlanId()));
            loadSalesPlanDetailListRequest.setScItemId(departmentResponse.getScItemId());
            loadSalesPlanDetailListRequest.setLimit(1000);
            Result<List<SalesPlanDetail>> salesPlanDetailResult = salesPlanDetailService.loadSalesPlanDetailList(loadSalesPlanDetailListRequest);
            if (Objects.isNull(salesPlanDetailResult)||CollectionUtils.isEmpty(salesPlanDetailResult.getResult())) {
                throw new FacadeException(ErrorMessage.code("OTS-02-004-01-16-044"));
            }
            Map<String, List<SalesPlanDetail>> salesPlanDetailDepartmentGroupMap = salesPlanDetailResult.getResult().stream().collect(Collectors.groupingBy(SalesPlanDetail::getOrgSalesDepartmentCode));

            //调整明细货品
            LoadSalesPlanAdjustDetailListRequest loadSalesPlanAdjustDetailListRequest = new LoadSalesPlanAdjustDetailListRequest();
            loadSalesPlanAdjustDetailListRequest.setAdjustId(Long.valueOf(departmentResponse.getAdjustId()));
            loadSalesPlanAdjustDetailListRequest.setScItemId(departmentResponse.getScItemId());
            loadSalesPlanAdjustDetailListRequest.setLimit(1000);
            Result<List<SalesPlanAdjustDetail>> salesPlanAdjustDetailResult = salesPlanAdjustDetailService.loadSalesPlanAdjustDetailList(loadSalesPlanAdjustDetailListRequest);
            if (Objects.isNull(salesPlanAdjustDetailResult)||CollectionUtils.isEmpty(salesPlanAdjustDetailResult.getResult())) {
                throw new FacadeException(ErrorMessage.code("OTS-02-004-01-16-044"));
            }
            Map<Long, SalesPlanAdjustDetail> adjustDetailMap = salesPlanAdjustDetailResult.getResult().stream().collect(Collectors.toMap(SalesPlanAdjustDetail::getPlanDetailId, Function.identity(),(v1, v2)->v1));

            //查询月度计划
            SalesPlanSDO salesPlanSDO = getSalesPlan(departmentResponse.getPlanId());

            List<SalesPlanAdjustDetailSDO> updateAdjustDetailList = new ArrayList<>();
            List<UpdateAdjustCountRequest> updatePlanDetailList = new ArrayList<>();
            //部门：调整量
            List<DepartmentResponse> mapList = departmentResponse.getMapList2();
            for (DepartmentResponse adjustSdo : mapList) {
                String departmentId = adjustSdo.getBizId();
                Integer firstDepartAdjustCount = adjustSdo.getMonthFirstAdjustCount();
                Integer middleDepartAdjustCount = adjustSdo.getMonthMiddleAdjustCount();
                Integer lastDepartAdjustCount = adjustSdo.getMonthLastAdjustCount();
                //部门调整量不能为空
                if(firstDepartAdjustCount==null || middleDepartAdjustCount==null || lastDepartAdjustCount==null){
                    throw new FacadeException(ErrorMessage.code("OTS-02-005-00-15-036"));
                }
                //校验任务量+调整量需大于等于0
                Integer departmentFirstTaskCount = departmentFirstTaskCountMap.get(departmentId);
                Integer departmentMiddleTaskCount = departmentMiddleTaskCountMap.get(departmentId);
                Integer departmentLastTaskCount = departmentLastTaskCountMap.get(departmentId);
                if(firstDepartAdjustCount+departmentFirstTaskCount<0 || middleDepartAdjustCount+departmentMiddleTaskCount<0  || lastDepartAdjustCount+departmentLastTaskCount<0){
                    throw new FacadeException(ErrorMessage.code("OTS-02-005-00-15-037"));
                }

                Integer departmentTaskCount = departmentTaskCountMap.get(departmentId);
                List<SalesPlanDetail> salesPlanDetailList = salesPlanDetailDepartmentGroupMap.get(departmentId);

                Integer departmentTaskCount2 = departmentTaskCount.equals(0)?salesPlanDetailList.size():departmentTaskCount;
                Integer firstDepartAdjustCount2 = firstDepartAdjustCount;
                Integer middleDepartAdjustCount2 = middleDepartAdjustCount;
                Integer lastDepartAdjustCount2 = lastDepartAdjustCount;
                for (SalesPlanDetail salesPlanDetail : salesPlanDetailList) {
                    //拿任务量计算得到占比   “上/中/下调整量”*{计划明细任务量/【部门+货品】任务量}
                    BigDecimal percentage = null;
                    //部门任务量为0 平分占比
                    Integer taskCount = departmentTaskCount.equals(0)?1:salesPlanDetail.getTaskCount();
                    if(departmentTaskCount2.equals(0)){
                        percentage = new BigDecimal(0);
                    }else{
                        percentage = new BigDecimal(taskCount).divide(new BigDecimal(departmentTaskCount2),4,BigDecimal.ROUND_HALF_UP);
                        departmentTaskCount2 = departmentTaskCount2-taskCount;
                    }

                    //得到分解的货品明细调整量
                    BigDecimal firstAdjustCount = new BigDecimal(firstDepartAdjustCount2).multiply(percentage).setScale(0,RoundingMode.DOWN);
                    firstDepartAdjustCount2 = new BigDecimal(firstDepartAdjustCount2).subtract(firstAdjustCount).intValue();
                    BigDecimal middleAdjustCount = new BigDecimal(middleDepartAdjustCount2).multiply(percentage).setScale(0,RoundingMode.DOWN);
                    middleDepartAdjustCount2 = new BigDecimal(middleDepartAdjustCount2).subtract(middleAdjustCount).intValue();
                    BigDecimal lastAdjustCount = new BigDecimal(lastDepartAdjustCount2).multiply(percentage).setScale(0,RoundingMode.DOWN);
                    lastDepartAdjustCount2 = new BigDecimal(lastDepartAdjustCount2).subtract(lastAdjustCount).intValue();

                    //更新调整明细数据
                    SalesPlanAdjustDetail salesPlanAdjustDetail = adjustDetailMap.get(salesPlanDetail.getId());
                    SalesPlanAdjustDetailSDO createSdo = bulidSalesPlanAdjustDetailSDO(salesPlanSDO,salesPlanAdjustDetail,salesPlanDetail,firstAdjustCount,middleAdjustCount,lastAdjustCount);
                    updateAdjustDetailList.add(createSdo);

                    //更新月度计划明细数据
                    UpdateAdjustCountRequest updateAdjustCountRequest = bulidUpdateAdjustCountRequest(createSdo);
                    updatePlanDetailList.add(updateAdjustCountRequest);
                }
            }

//            List<String> customerAddressIdList = salesPlanDetailResult.getResult().stream().map(x->x.getCustomerAddressId()).collect(Collectors.toList());
//            Integer deleteCount = salesPlanAdjustDetailAbility.deleteAdjustDetail(departmentResponse.getPlanId(),Lists.newArrayList(departmentResponse.getScItemId()),customerAddressIdList);
//            if(CollectionUtils.isNotEmpty(createAdjustDetailList)){
//                String createResult = salesPlanAdjustDetailAbility.batchCreateSalesPlanAdjustDetail(createAdjustDetailList);
//            }

            int updateCount = 0;
            for (SalesPlanAdjustDetailSDO x :updateAdjustDetailList) {
                SalesPlanAdjustDetailEntity salesPlanAdjustDetailEntity = SalesPlanAdjustDetailEntity.of(x);
                Integer count = salesPlanAdjustDetailEntity.doEdit();
                updateCount = updateCount+count;
            }
            log.info("SalesPlanScItemStatWriteServiceImpl_departmentAdjustDecomposition_salesPlanAdjustDetail_updateCount_size={}",updateCount);

            updateCount = 0;
            for (UpdateAdjustCountRequest x:updatePlanDetailList) {
                Result<Integer> updateResult = salesPlanLineWriteService.updateAdjustCount(x);
                updateCount = updateCount+updateResult.getResult();
            }
            log.info("SalesPlanScItemStatWriteServiceImpl_departmentAdjustDecomposition_salesPlanLine_updateAdjustCount_size={}",updateCount);
            if(updateCount == updatePlanDetailList.size()) {
                //更新成功后  进行汇总更新
                PlanStatServiceResponse planStatServiceResponse = salesPlanService.planStatService(PlanStatServiceRequest.builder().planId(departmentResponse.getPlanId()).build());
                if (!planStatServiceResponse.getSuccess()) {
                    throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-010"));
                }
            }else{
                throw new FacadeException(ErrorMessage.code("OTS-02-005-00-15-039"));
            }
        } catch (FacadeException | RepositoryException e) {
            throw new FacadeException(e.getErrorCode(), e.getErrorMessage());
        } catch (Throwable throwable) {
            log.error("SalesPlanScItemStatWriteServiceImpl_departmentAdjustDecomposition_occur_error ",throwable);
            throw new FacadeException(ErrorMessage.code("OTS-02-007-00-16-999"));
        }
        return Result.success(true);
    }

    /**
     * 渠道调整量分解
     * @param channelResponse
     * @return
     */
    @FacadeInvoker
    @Override
    public Result<Boolean> channelAdjustDecomposition(GoodsOwnershipDepartmentResponse channelResponse) {
        checkRequestParam(channelResponse);
        if (Objects.isNull(channelResponse.getMapList2())) {
            return Result.success(true);
        }
        String lockKey = SalesPlanLockKey.getAdjustCountDecompositionLockKey(channelResponse.getAdjustId(),channelResponse.getScItemId());
        try (RedisLock lock = new RedisLock(BcOrderConstants.REDIS_CACHE_CODE(), lockKey)) {
            boolean locked = lock.lock();
            if (!locked) {
                return Result.fail("OTS-02-007-00-16-001", "不能同时分解相同货品调整量，请稍候操作！");
            }

            //查询渠道货品维度汇总数据
            Result<List<PlanScItem>> channelStatResult = planScItemService.loadPlanScItemList(LoadPlanScItemListRequest.builder()
                    .planId(channelResponse.getPlanId())
                    .scItemId(channelResponse.getScItemId())
                    .poolType(channelResponse.getPoolType())
                    .bizType(SalesStatBizTypeEnum.SALES_CHANNEL.getBizType())
                    .build());
            if (CollectionUtils.isEmpty(channelStatResult.getResult())) {
                throw new FacadeException(ErrorMessage.code("OTS-02-005-00-15-038"));
            }
            //渠道：任务量
            List<PlanScItem> filterList = channelStatResult.getResult().stream().filter(t -> t.getBizId() != null).collect(Collectors.toList());
            Map<String, Integer> channelTaskCountMap = filterList.stream().collect(Collectors.toMap(PlanScItem::getBizId, PlanScItem::getTaskCount, (k1, k2) -> k1));
            Map<String, Integer> channelFirstTaskCountMap = filterList.stream().collect(Collectors.toMap(PlanScItem::getBizId, PlanScItem::getMonthFirstTaskCount, (k1, k2) -> k1));
            Map<String, Integer> channelMiddleTaskCountMap = filterList.stream().collect(Collectors.toMap(PlanScItem::getBizId, PlanScItem::getMonthMiddleTaskCount, (k1, k2) -> k1));
            Map<String, Integer> channelLastTaskCountMap = filterList.stream().collect(Collectors.toMap(PlanScItem::getBizId, PlanScItem::getMonthLastTaskCount, (k1, k2) -> k1));

            //计划明细货品：任务量
            LoadSalesPlanDetailListRequest loadSalesPlanDetailListRequest = new LoadSalesPlanDetailListRequest();
            loadSalesPlanDetailListRequest.setPlanId(Long.valueOf(channelResponse.getPlanId()));
            loadSalesPlanDetailListRequest.setScItemId(channelResponse.getScItemId());
            loadSalesPlanDetailListRequest.setLimit(1000);
            Result<List<SalesPlanDetail>> salesPlanDetailResult = salesPlanDetailService.loadSalesPlanDetailList(loadSalesPlanDetailListRequest);
            if (Objects.isNull(salesPlanDetailResult)||CollectionUtils.isEmpty(salesPlanDetailResult.getResult()) || salesPlanDetailResult.getTotal() == 0) {
                throw new FacadeException(ErrorMessage.code("OTS-02-004-01-15-043"));
            }
            Map<String, List<SalesPlanDetail>> salesPlanDetailChannelGroupMap = salesPlanDetailResult.getResult().stream().collect(Collectors.groupingBy(SalesPlanDetail::getOrgSalesChannelCode));

            //调整明细货品
            LoadSalesPlanAdjustDetailListRequest loadSalesPlanAdjustDetailListRequest = new LoadSalesPlanAdjustDetailListRequest();
            loadSalesPlanAdjustDetailListRequest.setAdjustId(Long.valueOf(channelResponse.getAdjustId()));
            loadSalesPlanAdjustDetailListRequest.setScItemId(channelResponse.getScItemId());
            loadSalesPlanAdjustDetailListRequest.setLimit(1000);
            Result<List<SalesPlanAdjustDetail>> salesPlanAdjustDetailResult = salesPlanAdjustDetailService.loadSalesPlanAdjustDetailList(loadSalesPlanAdjustDetailListRequest);
            if (Objects.isNull(salesPlanAdjustDetailResult)||CollectionUtils.isEmpty(salesPlanAdjustDetailResult.getResult())) {
                throw new FacadeException(ErrorMessage.code("OTS-02-004-01-16-044"));
            }
            Map<Long, SalesPlanAdjustDetail> adjustDetailMap = salesPlanAdjustDetailResult.getResult().stream().collect(Collectors.toMap(SalesPlanAdjustDetail::getPlanDetailId, Function.identity(),(v1, v2)->v1));

            //查询月度计划
            SalesPlanSDO salesPlanSDO = getSalesPlan(channelResponse.getPlanId());

            List<SalesPlanAdjustDetailSDO> updateAdjustDetailList = new ArrayList<>();
            List<UpdateAdjustCountRequest> updatePlanDetailList = new ArrayList<>();
            //渠道：调整量
            List<DepartmentResponse> mapList = channelResponse.getMapList2();
            for (DepartmentResponse adjustSdo : mapList) {
                String channelId = adjustSdo.getBizId();
                Integer firstChannelAdjustCount = adjustSdo.getMonthFirstAdjustCount();
                Integer middleChannelAdjustCount = adjustSdo.getMonthMiddleAdjustCount();
                Integer lastChannelAdjustCount = adjustSdo.getMonthLastAdjustCount();
                //渠道调整量不能为空
                if(firstChannelAdjustCount==null || middleChannelAdjustCount==null || lastChannelAdjustCount==null){
                    throw new FacadeException(ErrorMessage.code("OTS-02-005-00-15-036"));
                }
                //校验任务量+调整量需大于等于0
                Integer channelFirstTaskCount = channelFirstTaskCountMap.get(channelId);
                Integer channelMiddleTaskCount = channelMiddleTaskCountMap.get(channelId);
                Integer channelLastTaskCount = channelLastTaskCountMap.get(channelId);
                if(firstChannelAdjustCount+channelFirstTaskCount<0 || middleChannelAdjustCount+channelMiddleTaskCount<0  || lastChannelAdjustCount+channelLastTaskCount<0){
                    throw new FacadeException(ErrorMessage.code("OTS-02-005-00-15-037"));
                }

                Integer channelTaskCount = channelTaskCountMap.get(channelId);
                List<SalesPlanDetail> salesPlanDetailList = salesPlanDetailChannelGroupMap.get(channelId);

                Integer channelTaskCount2 = channelTaskCount.equals(0)?salesPlanDetailList.size():channelTaskCount;
                Integer firstChannelAdjustCount2 = firstChannelAdjustCount;
                Integer middleChannelAdjustCount2 = middleChannelAdjustCount;
                Integer lastChannelAdjustCount2 = lastChannelAdjustCount;
                for (SalesPlanDetail salesPlanDetail : salesPlanDetailList) {
                    //拿任务量计算得到占比   “上/中/下调整量”*{计划明细任务量/【渠道+货品】任务量}
                    //渠道任务量为0 平分占比
                    Integer taskCount = channelTaskCount.equals(0)?1:salesPlanDetail.getTaskCount();
                    BigDecimal percentage = null;
                    if(channelTaskCount2.equals(0)){
                        percentage = new BigDecimal(0);
                    }else{
                        percentage = new BigDecimal(taskCount).divide(new BigDecimal(channelTaskCount2),4,BigDecimal.ROUND_HALF_UP);
                        channelTaskCount2 = channelTaskCount2-taskCount;
                    }

                    //得到分解的货品明细调整量
                    BigDecimal firstAdjustCount = new BigDecimal(firstChannelAdjustCount2).multiply(percentage).setScale(0,RoundingMode.DOWN);
                    firstChannelAdjustCount2 = new BigDecimal(firstChannelAdjustCount2).subtract(firstAdjustCount).intValue();
                    BigDecimal middleAdjustCount = new BigDecimal(middleChannelAdjustCount2).multiply(percentage).setScale(0,RoundingMode.DOWN);
                    middleChannelAdjustCount2 = new BigDecimal(middleChannelAdjustCount2).subtract(middleAdjustCount).intValue();
                    BigDecimal lastAdjustCount = new BigDecimal(lastChannelAdjustCount2).multiply(percentage).setScale(0,RoundingMode.DOWN);
                    lastChannelAdjustCount2 = new BigDecimal(lastChannelAdjustCount2).subtract(lastAdjustCount).intValue();

                    //更新调整明细数据
                    SalesPlanAdjustDetail salesPlanAdjustDetail = adjustDetailMap.get(salesPlanDetail.getId());
                    SalesPlanAdjustDetailSDO createSdo = bulidSalesPlanAdjustDetailSDO(salesPlanSDO,salesPlanAdjustDetail,salesPlanDetail,firstAdjustCount,middleAdjustCount,lastAdjustCount);
                    updateAdjustDetailList.add(createSdo);

                    //更新月度计划明细数据
                    UpdateAdjustCountRequest updateAdjustCountRequest = bulidUpdateAdjustCountRequest(createSdo);
                    updatePlanDetailList.add(updateAdjustCountRequest);
                }
            }

//            List<String> customerAddressIdList = salesPlanDetailResult.getResult().stream().map(x->x.getCustomerAddressId()).collect(Collectors.toList());
//            Integer deleteCount = salesPlanAdjustDetailAbility.deleteAdjustDetail(channelResponse.getPlanId(), Lists.newArrayList(channelResponse.getScItemId()), customerAddressIdList);
//            if(CollectionUtils.isNotEmpty(createAdjustDetailList)) {
//                String createResult = salesPlanAdjustDetailAbility.batchCreateSalesPlanAdjustDetail(createAdjustDetailList);
//            }

            int updateCount = 0;
            for (SalesPlanAdjustDetailSDO x :updateAdjustDetailList) {
                SalesPlanAdjustDetailEntity salesPlanAdjustDetailEntity = SalesPlanAdjustDetailEntity.of(x);
                Integer count = salesPlanAdjustDetailEntity.doEdit();
                updateCount = updateCount+count;
            }
            log.info("SalesPlanScItemStatWriteServiceImpl_channelAdjustDecomposition_salesPlanAdjustDetail_updateCount_size={}",updateCount);

            updateCount = 0;
            for (UpdateAdjustCountRequest x:updatePlanDetailList) {
                Result<Integer> updateResult = salesPlanLineWriteService.updateAdjustCount(x);
                updateCount = updateCount+updateResult.getResult();
            }
            log.info("SalesPlanScItemStatWriteServiceImpl_channelAdjustDecomposition_salesPlanLine_updateAdjustCount_size={}",updateCount);
            if(updateCount == updatePlanDetailList.size()){
                //更新成功后  进行汇总更新
                PlanStatServiceResponse planStatServiceResponse = salesPlanService.planStatService(PlanStatServiceRequest.builder().planId(channelResponse.getPlanId()).build());
                if (!planStatServiceResponse.getSuccess()) {
                    throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-010"));
                }
            }else{
                throw new FacadeException(ErrorMessage.code("OTS-02-005-00-15-039"));
            }
        } catch (FacadeException | RepositoryException e) {
            throw new FacadeException(e.getErrorCode(), e.getErrorMessage());
        } catch (Throwable throwable) {
            log.error("SalesPlanScItemStatWriteServiceImpl_channelAdjustDecomposition_occur_error ",throwable);
            throw new FacadeException(ErrorMessage.code("OTS-02-007-00-16-999"));
        }
        return Result.success(true);
    }

    private void checkRequestParam(GoodsOwnershipDepartmentResponse channelResponse){
        if (StringUtils.isBlank(channelResponse.getPlanId())) {
            throw new FacadeException(ErrorMessage.code("OTS-02-001-00-15-006"));
        }
        if (StringUtils.isBlank(channelResponse.getAdjustId())) {
            throw new FacadeException(ErrorMessage.code("OTS-02-005-00-15-018"));
        }
        if (StringUtils.isBlank(channelResponse.getScItemId())) {
            throw new FacadeException(ErrorMessage.code("OTS-01-005-02-15-012"));
        }
        if (Objects.isNull(channelResponse.getPoolType())) {
            throw new FacadeException(ErrorMessage.code("OTS-02-004-01-15-002"));
        }
    }

    private SalesPlanAdjustDetailSDO bulidSalesPlanAdjustDetailSDO(SalesPlanSDO salesPlanSDO,SalesPlanAdjustDetail salesPlanAdjustDetail,SalesPlanDetail salesPlanDetail,BigDecimal firstAdjustCount,BigDecimal middleAdjustCount,BigDecimal lastAdjustCount) {
        // 构建失焦保存的sdo
        SalesPlanAdjustDetailSDO createAdjustDetailSDO = SalesPlanAdjustDetailSDO.builder().build();
        BeanUtils.copyProperties(salesPlanDetail, createAdjustDetailSDO);
        createAdjustDetailSDO.setId(salesPlanAdjustDetail.getId());
        createAdjustDetailSDO.setPlanId(salesPlanSDO.getId().toString());
        createAdjustDetailSDO.setPlanDetailId(salesPlanDetail.getId());
        createAdjustDetailSDO.setAdjustId(salesPlanAdjustDetail.getAdjustId());
        createAdjustDetailSDO.setStatus(SalesPlanLineStatusEnum.FINISH.getStatus());
        createAdjustDetailSDO.setCreator(null);
        createAdjustDetailSDO.setUpdater(null);
        createAdjustDetailSDO.setGmtCreate(null);
        createAdjustDetailSDO.setGmtModified(null);

        //调整量
        Integer adjustCount = firstAdjustCount.intValue()+middleAdjustCount.intValue()+lastAdjustCount.intValue();
        createAdjustDetailSDO.setAdjustCount(adjustCount);
        createAdjustDetailSDO.setMonthFirstAdjustCount(firstAdjustCount.intValue());
        createAdjustDetailSDO.setMonthMiddleAdjustCount(middleAdjustCount.intValue());
        createAdjustDetailSDO.setMonthLastAdjustCount(lastAdjustCount.intValue());

        //折前调整金额
        long costInsuranceFreight = Objects.nonNull(createAdjustDetailSDO.getCostInsuranceFreight()) ? createAdjustDetailSDO.getCostInsuranceFreight() : 0;
        long beforeAdjustMoney = createAdjustDetailSDO.getAdjustCount() * costInsuranceFreight;
        createAdjustDetailSDO.setBeforeAdjustMoney(beforeAdjustMoney);
        //折后调整金额  折后调整金额=折前调整金额*(1-预估价格折扣率)
        createAdjustDetailSDO.calculateAdjustMoney(salesPlanSDO.getEstimateDiscount());
        createAdjustDetailSDO.calculateAdjustSatisfaction();
        //到岸折前调整金额
        long outboundPrice = Objects.nonNull(createAdjustDetailSDO.getOutboundPrice()) ? createAdjustDetailSDO.getOutboundPrice() : 0;
        long beforeMonthOutboundMoney = createAdjustDetailSDO.getAdjustCount() * outboundPrice;
        createAdjustDetailSDO.setBeforeMonthOutboundMoney(beforeMonthOutboundMoney);
        //到岸折后金额 到岸折后金额=到岸折前金额*(1-预估价格折扣率)
        createAdjustDetailSDO.calculateMonthOutboundMoney(salesPlanSDO.getEstimateDiscount());
        //折前满足度=（任务量+调整提报量）*货品常规价
        Integer taskCount = Objects.isNull(createAdjustDetailSDO.getTaskCount()) ? 0 : createAdjustDetailSDO.getTaskCount();
        Integer taskAdjustCount = taskCount + createAdjustDetailSDO.getAdjustCount();
        //折前任务金额=（任务量+调整提报量）*货品常规价
        Long costInsuranceFreight1 = Objects.nonNull(createAdjustDetailSDO.getCostInsuranceFreight()) ? createAdjustDetailSDO.getCostInsuranceFreight() : 0;
        Long beforeTaskMoney = taskCount * costInsuranceFreight1;
        //落库的折前任务金额（任务量*单价）
        createAdjustDetailSDO.setBeforeTaskMoney(beforeTaskMoney);
        //不落库的任务金额（任务量+调整提报量）*货品常规价 用来计算满足度
        long notBeforeTaskMoney = taskAdjustCount * costInsuranceFreight1;
        //折前满足度=(折前任务金额/折前合同金额)
        BigDecimal beforeContractSatisfaction = CalculatePercentage.retainTwo(notBeforeTaskMoney, createAdjustDetailSDO.getBeforeMonthContractMoney());
        createAdjustDetailSDO.setBeforeContractSatisfaction(beforeContractSatisfaction);
        //折后任务金额=（任务量+调整提报量）*货品常规价*（1-预估价格折扣率）
        createAdjustDetailSDO.calculateTaskMoney(salesPlanSDO.getEstimateDiscount());
        //折后满足度=(折后任务金额/折后合同金额)
        BigDecimal contractSatisfaction = CalculatePercentage.retainTwoBigDecimal(new BigDecimal(createAdjustDetailSDO.getTaskMoney()), new BigDecimal(createAdjustDetailSDO.getMonthContractMoney()));
        createAdjustDetailSDO.setContractSatisfaction(contractSatisfaction);

//        //调整新数据标识
//        SalesPlanAdjustDetailFeatures salesPlanAdjustDetailFeatures = new SalesPlanAdjustDetailFeatures();
//        salesPlanAdjustDetailFeatures.setIsHistory(false);
//        createAdjustDetailSDO.setFeatures(JSONObject.toJSONString(salesPlanAdjustDetailFeatures));
        return createAdjustDetailSDO;
    }

    private UpdateAdjustCountRequest bulidUpdateAdjustCountRequest(SalesPlanAdjustDetailSDO createSdo){
        UpdateAdjustCountRequest updateAdjustCountRequest = new UpdateAdjustCountRequest();
        updateAdjustCountRequest.setId(createSdo.getPlanDetailId());
        updateAdjustCountRequest.setAdjustCount(createSdo.getAdjustCount());
        updateAdjustCountRequest.setAdjustMoney(createSdo.getAdjustMoney());
        updateAdjustCountRequest.setBeforeAdjustMoney(createSdo.getBeforeAdjustMoney());
        updateAdjustCountRequest.setMonthFirstAdjustCount(createSdo.getMonthFirstAdjustCount());
        updateAdjustCountRequest.setMonthMiddleAdjustCount(createSdo.getMonthMiddleAdjustCount());
        updateAdjustCountRequest.setMonthLastAdjustCount(createSdo.getMonthLastAdjustCount());
        return updateAdjustCountRequest;
    }

    private SalesPlanSDO getSalesPlan(String planId){
        QuerySalesPlanRequest querySalesPlanRequest = new QuerySalesPlanRequest();
        querySalesPlanRequest.setId(planId);
        Result<SalesPlanSDO> salesPlan = salesPlanQueryService.getSalesPlan(querySalesPlanRequest);
        SalesPlanSDO salesPlanSDO = salesPlan.getResult();
        return salesPlanSDO;
    }
}